package com.hugedata.cdn.base.util;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/** 公共日期时间操作工具类 */
public class DateTime {
    /** DateTimeFormat1 = "yyyy-MM-dd HH:mm:ss" */
    public static final String DateTimeFormat1 = "yyyy-MM-dd HH:mm:ss";

    /** DateTimeFormat2 = "yyyy-MM-dd HH:mm:ss:SSS" */
    public static final String DateTimeFormat2 = "yyyy-MM-dd HH:mm:ss:SSS";

    /** DateFormat1 = "yyyy-MM-dd" */
    public static final String DateFormat1     = "yyyy-MM-dd";

    /** DateFormat2 = "yyyy/MM/dd" */
    public static final String DateFormat2     = "yyyy/MM/dd";

    /** DateFormat3 = "yyyy.MM.dd" */
    public static final String DateFormat3     = "yyyy.MM.dd";

    /** TimeFormat1 = "HH:mm:ss" */
    public static final String TimeFormat1     = "HH:mm:ss";

    /** TimeFormat2 = "HH:mm:ss:SSS" */
    public static final String TimeFormat2     = "HH:mm:ss:SSS";

    /** _HH : 一小时的毫秒数 60 * 60 * 1000 */
    public static final int    _HH             = 60 * 60 * 1000;

    /** _MM : 一分钟的毫秒数 60 * 1000 */
    public static final int    _MM             = 60 * 1000;

    /** _SS : 一秒的毫秒数 1000 */
    public static final int    _SS             = 1000;

    /**
     * @return 返回文本信息的日期对应的格林威治标准时间（1970年1月1日00:00:00.000）的偏移量,单位是毫秒。 1秒=1000毫秒。
     * @param format
     *            "yyyy-MM-dd HH:mm:ss:SSS"或"yyyy-MM-dd HH:mm:ss"。
     */
    public static long dateTimeParse(String datetime, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        try {
            Date date = sdf.parse(datetime);
            return date.getTime();
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }
        return 0;
    }

    /**
     * @return 返回测试时间是否在beginTime和endTime之间，如果在返回true，不在返回false。
     * @param beginTime
     *            开始时间。格式为："yyyy-MM-dd HH:mm:ss:SSS"或者"yyyy-MM-dd HH:mm:ss"。
     * @param endTime
     *            结束时间。格式同上。
     * @param testTime
     *            被测试的时间。格式同上。
     * @param timeFormat
     *            共同的格式为："yyyy-MM-dd HH:mm:ss:SSS"或"yyyy-MM-dd
     *            HH:mm:ss"，请使用本类中提供的类型 。
     */
    public static boolean isInTwoTime(String beginTime, String endTime,
            String testTime, String timeFormat) {
        long begin = DateTime.dateTimeParse(beginTime, timeFormat);
        long end = DateTime.dateTimeParse(endTime, timeFormat);
        long test = DateTime.dateTimeParse(testTime, timeFormat);
        if (test > begin && test < end) {
            return true;
        }
        return false;
    }

    /**
     * @param dateFormat
     *            请使用本类提供的类型。格式："yyyy-MM-dd"或"yyyy/MM/dd"或"yyyy.MM.dd" 。
     * @return 返回指定格式的当前日期
     */
    public static String currentDate(String dateFormat) {
        Date d = new java.util.Date();
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        return sdf.format(d);
    }

    /**
     * @param timeFormat
     *            请使用本类提供的类型。格式："HH:mm:ss"或"HH:mm:ss:SSS" 。
     * @return 返回指定格式的当前时间
     */
    public static String currentTime(String timeFormat) {
        Date d = new java.util.Date();
        SimpleDateFormat sdf = new SimpleDateFormat(timeFormat);
        return sdf.format(d);
    }

    /**
     * @param format
     *            请使用本类提供的类型。格式："yyyy-MM-dd HH:mm:ss:SSS"或"yyyy-MM-dd HH:mm:ss"。
     * @return 返回指定格式的当前日期时间
     */
    public static String currentDateTime(String format) {
        Date d = new java.util.Date();
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(d);
    }

    /** 获得当前时间,格式为："yyyy-MM-dd HH:mm:ss.SSS" */
    public static String currentDateTime() {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(Calendar
                .getInstance().getTime());
    }

    /**
     * @return 返回当前系统时间的格林威治毫秒时。
     * @param format
     *            指定返回的值精确到秒还是毫秒。请使用本类提供的类型。格式："yyyy-MM-dd HH:mm:ss:SSS"精确到毫秒 或
     *            "yyyy-MM-dd HH:mm:ss"精确到秒。
     */
    public static long currentDateTimeGreenwich(String format) {
        Calendar rightNow = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        String sysDatetime = sdf.format(rightNow.getTime());
        return DateTime.dateTimeParse(sysDatetime, format);
    }

    /**
     * 返回以毫秒为单位的当前时间。注意，当返回值的时间单位是毫秒时，值的粒度取决于底层操作系统，并且粒度可能更大。
     * 例如，许多操作系统以几十毫秒为单位测量时间。 请参阅 Date 类的描述，了解可能发生在“计算机时间”和协调世界时
     * （UTC）之间的细微差异的讨论。 返回： 当前时间与协调世界时 1970 年 1 月 1 日午夜之间的时间差（以毫秒为单 位测量）。
     * 
     * @see Date
     */
    public static long currentTimeMillis() {
        return System.currentTimeMillis();
    }

    /**
     * 返回最准确的可用系统计时器的当前值，以毫微秒为单位。此方法只能用于测量已过的时间，与系统或钟表时间的其他任何时间概念无关。
     * 返回值表示从某一固定但任意的时间算起的毫微秒数（或许从以后算起，所以该值可能为负）。此方法提供毫微秒的精度，但不是必要的毫
     * 微秒的准确度。它对于值的更改频率没有作出保证。在取值范围大于约 292 年（263 毫微秒）的连续调用的不同点在于：由于数字溢出，
     * 将无法准确计算已过的时间。
     */
    // 例如，测试某些代码执行的时间长度：
    // long startTime = System.nanoTime();
    // //... the code being measured ...
    // long estimatedTime = System.nanoTime() - startTime;
    //
    public static long nanoTime() {
        return System.nanoTime();
    }

    /**
     * @return 把毫秒时间转换成小时分钟秒格式 HH:mm:ss
     */
    public static String toHHmmss(final long millisecond) {
        long h = millisecond / _HH;
        // int m = (int) ((millisecond - h * _HH) / _MM);
        // int s = (int) ((millisecond - h * _HH - m * _MM) / _SS);
        SimpleDateFormat sdf = new SimpleDateFormat(":mm:ss");
        return h + sdf.format(millisecond);
    }

    /**
     * @return 把毫秒时间转换成小时分钟秒毫秒格式 HH:mm:ss:SSS
     */
    public static String toHHmmssSSS(final long millisecond) {
        long h = millisecond / _HH;
        // int m = (int) ((millisecond - h * _HH) / _MM);
        // int s = (int) ((millisecond - h * _HH - m * _MM) / _SS);
        // int ms = (int) (millisecond - h * _HH - m * _MM - s * _SS);
        SimpleDateFormat sdf = new SimpleDateFormat(":mm:ss:SSS");
        return h + sdf.format(millisecond);
    }

    public static void main(String[] args) {
        // new MyTimeSetting().result();
        System.out.println("今天是:" + DateTime.currentDate(DateTime.DateFormat1));
        System.out.println("时间是：" + DateTime.currentTime(DateTime.TimeFormat1));
        System.out.println("现在是："
                + DateTime.currentDateTime(DateTime.DateTimeFormat1));
        long l = DateTime.currentDateTimeGreenwich(DateTime.DateTimeFormat1);
        System.out.println("格林威治毫秒是:" + l);

        System.out.println("距离格林威治时间：" + DateTime.toHHmmss(l));

        System.out.println(System.currentTimeMillis());
        System.out.println(System.nanoTime());
    }
}

/** -----------------------------分隔线--------------------------------- */
/**
 * 项目中要求 获取java.sql.Timestamp 类型 中的时、分、秒、日期，然后进行比较。 比如 2011-09-21 08:30:00
 * 我要获取里面的 8点30分 然后在程序中判断。 String m= 8:30-9:30之间则设置A 9:30-10:00则设置为B
 * 10:00-10:30则设置为C 10:30-11:00之间则设置D 11:00-11:30则设置为E 11:30-12:30则设置为F
 */
class MyTimeSetting {
    public final String sBegin = "2011-09-21 08:30:00";
    public final String test   = "2011-09-21 09:33:00";
    public String       state  = "";

    public void result() {
        long lBegin = DateTime.dateTimeParse(sBegin, DateTime.DateTimeFormat1);
        long lTest = DateTime.dateTimeParse(test, DateTime.DateTimeFormat1);
        int choice = (int) ((lTest - lBegin) / DateTime._HH);
        switch (choice) {
        case 0:
            state = "A";
            break;
        case 1:
            state = "B";
            break;
        case 2:
            state = "C";
            break;
        case 3:
            state = "D";
            break;
        case 4:
            state = "E";
            break;
        case 5:
            state = "F";
            break;
        default:
            state = "error";
        }
        System.out.println(test + " --- " + state);
    }
}
